package org.stream.answerduel.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.core.env.Environment;
import org.stream.answerduel.service.Async.AsyncServiceImpl;
import org.stream.answerduel.util.SnowflakeIdWorker;
import org.stream.answerduel.vo.MatchingUser;
import org.stream.answerduel.vo.RobotVo;

import javax.annotation.PostConstruct;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;

/**
 * 功能描述：负责制造机器人，填充机器人，激活机器人
 *
 * @Auther: 苏建誉
 * @Date: 2019/7/10 22:12
 */
@Service
@Slf4j
public class RobotService implements Runnable{
    private static RobotService instance=null;

    @Autowired
    AsyncServiceImpl asyncService;

    @Autowired
    SnowflakeIdWorker idProducer;

    @Autowired
    Environment env;

    @Autowired
    MatchService matchService;

    @Autowired
    NameBuilderService nameBuilderService;
    public enum Grade{simple,medium,difficulty,hell}

    private Map<Long, RobotVo> robotList ;

    private Random  random= new Random();

    @PostConstruct
    public void Init(){
        instance=this;
        robotList= new ConcurrentHashMap<Long, RobotVo>();
        Thread thread=new Thread(this);
        thread.start();
    }

    public static RobotService getInstance() {
        return instance;
    }
    /**
     * 功能描述：激活机器人
     *
     *@param id 机器人id
     *@param answer  正确答案
     */
    public void onDuty(Long id, Long roomId, int answer){
        asyncService.asyncInvoke(() -> {
            RobotVo robot=findRobotById(id);
            int num=new Random().nextInt(10);
            try {
                Thread.sleep(robot.getTime()*1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if(num<robot.getProb()){

                matchService.answer(robot.getId(),roomId,answer);
            }
            else{
                int robotChoice;
                do{
                    robotChoice=new Random().nextInt(4)+1;
                }while(robotChoice==answer);
                matchService.answer(robot.getId(),roomId,robotChoice);
            }
        });

    }

    /**
     * 功能描述：根据id查找机器人
     *
     *@param id 机器人id
     *
     */
    public RobotVo findRobotById(Long id){
        for (Map.Entry<Long, RobotVo> entry : robotList.entrySet()) {
            if(entry.getValue().getId()==id){
                return entry.getValue();
            }
        }
        return null;
    }
    /**
     * 功能描述：负责产生机器人
     *
     *@param grade 机器人等级
     */
    public RobotVo createRobot(Grade grade){
        RobotVo robot = null;
        switch(grade){
            case simple:{
                robot = new RobotVo(Integer.parseInt(env.getProperty("robot.simple.prob")),Integer.parseInt(env.getProperty("robot.simple.time")));
                Long id=idProducer.nextId();
                robot.setId(id);
                robot.setWechatID("robot simple "+id.toString());
                robot.setNickName(nameBuilderService.build());
                robot.setRightCount(30);
                robot.setWrongCount(50);
                robot.setScore(random.nextInt(100));
                robot.setAvatarUrl("/static/images/user.png");
                break;
            }
            case medium:{
                robot = new RobotVo(Integer.parseInt(env.getProperty("robot.medium.prob")),Integer.parseInt(env.getProperty("robot.medium.time")));
                Long id=idProducer.nextId();
                robot.setId(id);
                robot.setWechatID("robot medium "+id.toString());
                robot.setNickName(nameBuilderService.build());
                robot.setRightCount(100);
                robot.setWrongCount(30);
                robot.setScore(random.nextInt(100)+300);
                robot.setAvatarUrl("/static/images/user.png");
                break;
            }
            case difficulty:{
                robot = new RobotVo(Integer.parseInt(env.getProperty("robot.difficulty.prob")),Integer.parseInt(env.getProperty("robot.difficulty.time")));
                Long id=idProducer.nextId();
                robot.setId(id);
                robot.setWechatID("robot difficulty "+id.toString());
                robot.setNickName(nameBuilderService.build());
                robot.setRightCount(500);
                robot.setWrongCount(150);
                robot.setScore(random.nextInt(500)+2000);
                robot.setAvatarUrl("/static/images/user.png");
                break;
            }
            case hell:{
                robot = new RobotVo(Integer.parseInt(env.getProperty("robot.hell.prob")),Integer.parseInt(env.getProperty("robot.hell.time")));
                Long id=idProducer.nextId();
                robot.setId(id);
                robot.setWechatID("robot hell "+id.toString());
                robot.setNickName(nameBuilderService.build());
                robot.setRightCount(1000);
                robot.setWrongCount(300);
                robot.setScore(random.nextInt(2000)+5000);
                robot.setAvatarUrl("/static/images/user.png");
                break;
            }
        }
        return robot;
    }
    /**
     * 功能描述：往匹配队列填充机器人
     *
     *
     */
    private void fillRobot(){
        if(robotList.isEmpty()){
            for(int i=0;i<1000;i++){
                try {
                    RobotVo m1=createRobot(Grade.simple);
                    m1.setOnDuty(true);
                    matchService.startMatch(new MatchingUser(m1,-1));
                    robotList.put(m1.getId(),m1);
                    //log.info(m1.getNickName()+"投入使用");

                    RobotVo m2=createRobot(Grade.medium);
                    m2.setOnDuty(true);
                    matchService.startMatch(new MatchingUser(m2,-1));
                    robotList.put(m2.getId(),m2);
                    //log.info(m2.getNickName()+"投入使用");

                    RobotVo m3=createRobot(Grade.difficulty);
                    m3.setOnDuty(true);
                    matchService.startMatch(new MatchingUser(m3,-1));
                    robotList.put(m3.getId(),m3);
                    //log.info(m3.getNickName()+"投入使用");

                    RobotVo m4=createRobot(Grade.hell);
                    m4.setOnDuty(true);
                    matchService.startMatch(new MatchingUser(m4,-1));
                    robotList.put(m4.getId(),m4);
                    //log.info(m4.getNickName()+"投入使用");
                } catch (Exception e) {
                    e.printStackTrace();
                } 
            }
        }
        else{
            for (Map.Entry<Long, RobotVo> entry : robotList.entrySet()) {
                if(!entry.getValue().isOnDuty()){
                    try {
                        matchService.startMatch(new MatchingUser(entry.getValue(),-1));
                        entry.getValue().setOnDuty(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                //System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
            }
        }
    }

    /**
     * 功能描述：Robot服务的线程函数
     *
     *
     */
    @Override
    public void run() {
        while(true){
            try {
                fillRobot();
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
